﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ParserCore;
using NumericalCalculations;

namespace Memory_Access
{
    public class FunctionTable : AbstractTable, ICloneable
    {
        private Dictionary<Identifier, FunctionImplementation> table;

        public FunctionTable()
        {
            table = new Dictionary<Identifier, FunctionImplementation> ();
        }

        public void AddParsedFunction(FunctionDefinitionStatement function)
        {
            MatlabFunction implementationInfo = new MatlabFunction(function);
            table.Add(function.FcnName, implementationInfo);
        }

        public void AddFunctions(Dictionary<string, string> functions)
        {
            foreach (string name in functions.Keys.AsEnumerable())
            {
                Identifier functionName = new Identifier(name);
                string functionCode;
                functionCode = functions[name];
                //bool success = functions.TryGetValue(name, out functionCode);
                //System.Diagnostics.Debug.Assert(success);
                table.Add(functionName, new MatlabFunction(functionCode));
            }
        }

        public void AddBuiltInFunctions()
        {
            Functions functions = new Functions();
            functions.addFunctions();

            foreach (Identifier id in Functions.FunctionsDictionary.Keys)
            {
                this.AddFunction(id, new BuiltInFunction(Functions.FunctionsDictionary[id]));
            }
        }

        public void AddFunctions(FunctionTable funcTable)
        {
            foreach (Identifier id in funcTable.GetAllFunctionsNames())
            {
                this.AddFunction(id, new BuiltInFunction(Functions.FunctionsDictionary[id]));
            }
        }

        public void AddFunction(Identifier id, BuiltInFunction bif)
        {
            table.Add(id, bif);
        }

        public void RemoveFunction(Identifier id)
        {
            table.Remove(id);
        }

        public void RemoveFunctions(List<Identifier> ids)
        {
            foreach (Identifier id in ids)
            {
                RemoveFunction(id);
            }
        }

        public FunctionImplementation LookUp(Identifier ID)
        {
            FunctionImplementation value;
            bool success = table.TryGetValue(ID, out value);
            if (!success) return null;
            else return value;
        }

        public List<Identifier> GetAllFunctionsNames()
        {
            return table.Keys.ToList();
        }

        public object Clone()
        {
            return this.MemberwiseClone();      // call clone method
        }
    }
}